package com.channel.temperature.collect.app.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import androidx.core.view.MotionEventCompat;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;

public class MyUtil {

    //高字节在前，也可使用  BigInteger
    public static byte[] intToBytes(int value) {
        return new byte[]{(byte) (value >>> 24),       //无符号右移，也可用>>
                (byte) (value >>> 16), (byte) (value >>> 8), (byte) value};
    }

    //低字节在前
    public static byte[] intToBytes_LSB(int value) {
        return new byte[]{(byte) value, (byte) (value >>> 8), (byte) (value >>> 16), (byte) (value >>> 24)       //无符号右移，也可用>>

        };
    }

    public static int bytesToInt(byte[] b) {
        return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24;

    }

    /**
     * 字节数组转为普通字符串（ASCII对应的字符）
     *
     * @param bytearray byte[]
     * @return String
     */
    public static String bytetoString(byte[] bytearray) {
        String result = "";
        char temp;

        int length = bytearray.length;
        for (int i = 0; i < length; i++) {
            temp = (char) bytearray[i];
            result += temp;
        }
        return result;
    }

    /**
     * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序，和和intToBytes（）配套使用
     *
     * @param src    byte数组
     * @param offset 从数组的第offset位开始
     * @return int数值
     */
    public static int bytesToIntLSB(byte[] src, int offset) {
        int value;
        value = (int) ((src[offset] & 0xFF) | ((src[offset + 1] & 0xFF) << 8) | ((src[offset + 2] & 0xFF) << 16) | ((src[offset + 3] & 0xFF) << 24));
        return value;
    }


    //ff cd 10 => "ff cd 10"

    /**
     * hex字符串转byte数组<br/>
     * 2个hex转为一个byte
     *
     * @param src
     * @return
     */
    public static byte[] hex2Bytes(String src) {
        byte[] res = new byte[src.length() / 2];
        char[] chs = src.toCharArray();
        for (int i = 0, c = 0; i < chs.length; i += 2, c++) {
            res[c] = (byte) (Integer.parseInt(new String(chs, i, 2), 16));
        }

        return res;
    }

    /**
     * byte数组转hex字符串<br/>
     * 一个byte转为2个hex字符
     *
     * @param src
     * @return
     */
    public static String bytes2Hex(byte[] src) {
        char[] res = new char[src.length * 2];
        final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        for (int i = 0, j = 0; i < src.length; i++) {
            res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
            res[j++] = hexDigits[src[i] & 0x0f];
        }

        return new String(res);
    }

    //10进制数字转换成完整的16进制字符串 比如 2 -> 01
    public static String numberToHexOne(int number) {
        return MyUtil.bytes2Hex(MyUtil.intToBytes(number)).substring(6, 8);
    }

    //10进制数字转换成完整的16进制字符串 比如 256 -> 0100,
    public static String numberToHexTwo(int number) {
        return MyUtil.bytes2Hex(MyUtil.intToBytes(number)).substring(4, 8);
    }

    //10进制数字转换成完整的16进制字符串 比如 256 -> 00000100,
    public static String numberToHexTwoNew(int number) {
        return MyUtil.bytes2Hex(MyUtil.intToBytes(number));
    }

    public static String bytes2Hex(byte[] src, int start, int len) {
        if (start + len > src.length) throw new ArrayIndexOutOfBoundsException();

        char[] res = new char[len * 2];
        final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        for (int i = start, j = 0; i < start + len; i++) {
            res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
            res[j++] = hexDigits[src[i] & 0x0f];
        }

        return new String(res);
    }

    //在主线程执行
    public static boolean runOnUiThread(Runnable runnable) {
        boolean ret = false;
        Handler handler = new Handler(Looper.getMainLooper());
        if (handler != null) {
            handler.post(runnable);
            ret = true;
        }

        return ret;
    }

    public static boolean runOnUiThreadDelayed(Runnable runnable, long delayMillis) {
        boolean ret = false;
        Handler handler = new Handler(Looper.getMainLooper());
        if (handler != null) {
            handler.postDelayed(runnable, delayMillis);
            ret = true;
        }

        return ret;
    }

    public static boolean isMainThread() {
        return Looper.myLooper() == Looper.getMainLooper();
    }

    //[0,256)
    public static int genRandomByte() {
        Random random = new Random();
        int ret = random.nextInt(256);
        return ret;
    }

    //byte 数组与 int 的相互转换
    public static int byteArrayToInt(byte[] b) {
        return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24;
    }

    public static byte[] intToByteArray(int a) {
        return new byte[]{(byte) ((a >> 24) & 0xFF), (byte) ((a >> 16) & 0xFF), (byte) ((a >> 8) & 0xFF), (byte) (a & 0xFF)};
    }

    /**
     * 将传递进来的参数拼接成 url
     */
    public static String createUrlFromParams(String url, Map<String, String> params) {
        try {
            StringBuilder sb = new StringBuilder();
            sb.append(url);
            if (url.indexOf('&') > 0 || url.indexOf('?') > 0) sb.append("&");
            else sb.append("?");
            for (Map.Entry<String, String> urlParams : params.entrySet()) {
                String urlValue = URLEncoder.encode(urlParams.getValue(), "UTF-8");
                sb.append(urlParams.getKey()).append("=").append(urlValue).append("&");
            }
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 日期转换成字符串
     *
     * @param date
     * @return str
     */
    public static String DateToStr(Date date) {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = format.format(date);
        return str;
    }

    public static String DateToStrFormat(Date date) {

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String str = format.format(date);
        return str;
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @return date
     */
    public static Date StrToDate(String str) {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    //"2016-06-30 12:38:49"   ->   160630123849
    public static byte[] dateTime2Buf(String strDateTime) {
        String[] sl = strDateTime.split(" ");

        String[] date = sl[0].split("-");
        String[] time = sl[1].split(":");

        byte[] buf;

        String year = date[0].substring(2);

        buf = MyUtil.hex2Bytes(year + date[1] + date[2] + time[0] + time[1] + time[2]);

        return buf;


    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            String hv = Integer.toHexString(b & MotionEventCompat.ACTION_MASK);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase();
    }

    public static byte[] dateTime2Buf1(String strDateTime, int week) {
        String[] sl = strDateTime.split(" ");

        String[] date = sl[0].split("-");
        String[] time = sl[1].split(":");

        byte[] buf;

        String year = date[0].substring(2);
        String str_week = String.format("%02d", week);

        buf = MyUtil.hex2Bytes(year + date[1] + date[2] + str_week + time[0] + time[1] + time[2]);

        return buf;


    }

    //把 0x16 0x06 0x01 0x23 0x54 0x23 这样的时间buf转换为"2016-06-01 23:54:23
    public static String dateTimeBuf2Str(byte[] buf) {
        String year, mon, day, hour, min, sec;

        year = "20" + Integer.toHexString(buf[0]);
        mon = Integer.toHexString(buf[1]);
        day = Integer.toHexString(buf[2]);
        hour = Integer.toHexString(buf[3]);
        min = Integer.toHexString(buf[4]);
        sec = Integer.toHexString(buf[5]);
        return String.format("%s-%s-%s %s:%s:%s", year, mon, day, hour, min, sec);

    }


    public static boolean strIsEmpty(String s) {
        if (s == null || s.trim().isEmpty()) return true;

        return false;
    }

    /**
     * 获得指定文件的byte数组
     */
    public static byte[] getFileBytes(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * 字符串转换为Ascii
     *
     * @return
     */
    public static String stringToAscii(String str) {
        StringBuffer sb = new StringBuffer();
        byte[] bs = str.getBytes();

        for (int i = 0; i < bs.length; i++) {
            sb.append(toHex(bs[i]));
        }
        return sb.toString();
    }

    public static String toHex(int n) {
        StringBuffer sb = new StringBuffer();
        if (n / 16 == 0) {
            return toHexUtil(n);
        } else {
            String t = toHex(n / 16);
            int nn = n % 16;
            sb.append(t).append(toHexUtil(nn));
        }
        return sb.toString();
    }

    public static String toHexUtil(int n) {
        String rt = "";
        switch (n) {
            case 10:
                rt += "A";
                break;
            case 11:
                rt += "B";
                break;
            case 12:
                rt += "C";
                break;
            case 13:
                rt += "D";
                break;
            case 14:
                rt += "E";
                break;
            case 15:
                rt += "F";
                break;
            default:
                rt += n;
        }
        return rt;
    }

    /**
     * Ascii转换为字符串
     *
     * @param value
     * @return
     */
    public static String asciiToString(String value) {
        StringBuffer sbu = new StringBuffer();
        String[] chars = value.split(",");
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }

    public static String bytes2Float(byte[] buf) {
        return new DecimalFormat("#0.00").format(ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN).getFloat());
    }

    public static String bytes2FloatOther(byte[] buf) {
        return new DecimalFormat("#0.000000").format(ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN).getFloat());
    }

    public static String bytes2DoubleString(byte[] buf) {
        return new DecimalFormat("#0.000000").format(ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN).getDouble());
    }

    public static Double bytes2Double(byte[] buf) {
        return ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN).getDouble();
    }

    public static String formatFloat(float value, int type, float defaultValue) {
        String result = "" + 0.00f;
        defaultValue = 0.00f;
        try {
            if (type == 2) {
                result = new DecimalFormat("#0.00").format(value);
            } else if (type == 3) {
                result = new DecimalFormat("#0.00").format(value);
            }
        } catch (NumberFormatException e) {
            result = "" + defaultValue;
            Log.e("测试formatFloat", "测试formatFloat  " + result);
        }
        return result;
    }

    public static Bitmap drawableToBitamp(Drawable drawable) {
        //声明将要创建的bitmap
        Bitmap bitmap = null;
        //获取图片宽度
        int width = drawable.getIntrinsicWidth();
        //获取图片高度
        int height = drawable.getIntrinsicHeight();
        //图片位深，PixelFormat.OPAQUE代表没有透明度，RGB_565就是没有透明度的位深，否则就用ARGB_8888。详细见下面图片编码知识。
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        //创建一个空的Bitmap
        bitmap = Bitmap.createBitmap(width, height, config);
        //在bitmap上创建一个画布
        Canvas canvas = new Canvas(bitmap);
        //设置画布的范围
        drawable.setBounds(0, 0, width, height);
        //将drawable绘制在canvas上
        drawable.draw(canvas);
        return bitmap;
    }

    public static byte[] convertToBytes(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); // 这里的参数可根据需要进行调整
        return stream.toByteArray();
    }

    /**
     * 根据文件后缀名获得对应的MIME类型。
     *
     * @param filePath
     */
    public static String getMimeType(String filePath) {
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        String mime = "text/plain";
        if (filePath != null) {
            try {
                mmr.setDataSource(filePath);
                mime = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
            } catch (IllegalStateException e) {
                return mime;
            } catch (IllegalArgumentException e) {
                return mime;
            } catch (RuntimeException e) {
                return mime;
            }
        }
        return mime;
    }

    public int getScreenOrientation(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (wm != null) {
            Display display = wm.getDefaultDisplay();
            return display.getRotation();
        }
        return 0;
    }

}
